/************************************************************************
This file is part of Polar4linux
Copyright (C) 2010-2011 Eric jrdn2
Portions Copyright (C) 2007 Matti Juvonen <mpj@iki.fi> (RS400 Tools)
Portions Copyright (C) 2006 Jani Hursti <jani.hursti@hut.fi>,
Portions Copyright (C) 2001-2003 Tom Oliveira e Silva

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
************************************************************************/

#include "advexbuilder.h"

advExBuilder::advExBuilder(QWidget *parent) : QWidget(parent)
{
	setupUi(this);
	connect(comboBoxPhaseBound,SIGNAL(currentIndexChanged ( int )), this, SLOT(setAdvExBoundStyle(int)) );
	connect(comboBoxPhaseTarget, SIGNAL(currentIndexChanged ( int )), this, SLOT(setAdvExTargetStyle(int)) );
	setAdvExBoundStyle(0);
	
	tableWidgetPhases->setColumnCount(1);
	QStringList labels4;
	labels4 << tr("phase name");
	tableWidgetPhases->setHorizontalHeaderLabels(labels4);
	tableWidgetPhases->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
	//tableWidgetPhases->verticalHeader()->hide();
	tableWidgetPhases->setShowGrid(true);
	
	displayedExercise=-1;
	displayedPhase=-1;
	
	connect(pushButtonGetAdvEx, SIGNAL(clicked()), this, SLOT(getExercises()));
	connect(pushButtonSetAdvEx, SIGNAL(clicked()), this, SLOT(setExercises()));
	connect(pushButtonNewPhase, SIGNAL(clicked()), this, SLOT(newPhase()));
	connect(pushButtonNewAdvExo, SIGNAL(clicked()), this, SLOT(newExercise()));
	connect(pushButtonDeleteAdvExo, SIGNAL(clicked()), this, SLOT(deleteExercise()));
	connect(pushButtonDeletePhase, SIGNAL(clicked()), this, SLOT(deletePhase()));
	connect(tableWidgetAdvancedEx, SIGNAL(cellClicked (int, int)), this, SLOT(savendisplayExercise(int)));//
	connect(tableWidgetPhases, SIGNAL(cellClicked (int, int)), this, SLOT(savendisplayPhase(int)));
	labelFrom->setVisible(false);
	labelTo1->setVisible(false);
	labelTo2->setVisible(false);
}

void advExBuilder::configure(int mode, polar4linuxInternals *internals0,polarLINUXio_advanced_exercises_list &list)
{
	internals=internals0;
	setMode(mode);
	setWorkingExerciseList(list);
}

void advExBuilder::setWorkingExerciseList(polarLINUXio_advanced_exercises_list &list)
{
	exList=&list;
}

void advExBuilder::setMode(int _mode)
{
	mode=_mode;
	tableWidgetAdvancedEx->setColumnCount(1);
	tableWidgetAdvancedEx->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
	tableWidgetAdvancedEx->verticalHeader()->hide();
	tableWidgetAdvancedEx->setShowGrid(true);
	
	if (mode==0)
	{
	//no date for advanced exercises
		dateEdit_Training->setVisible(false);
		timeEdit_Training->setVisible(false);
		label_2->setVisible(false);
		label_3->setVisible(false);
		QStringList labels5;
		labels5 << tr("adv. exercise name");
		tableWidgetAdvancedEx->setHorizontalHeaderLabels(labels5);
	}
	else
	{
		dateEdit_Training->setVisible(true);
		timeEdit_Training->setVisible(true);
		label_2->setVisible(true);
		label_3->setVisible(true);
		QStringList labels5;
		labels5 << tr("training name");
		tableWidgetAdvancedEx->setHorizontalHeaderLabels(labels5);
	}
}


void advExBuilder::setAdvExBoundStyle(int val)
{
	if (val==0) //manual
	{
		groupBoxTarget->setVisible(true);
		labelTo1->setVisible(false);
		widgetPhaseBounds->setStyle(noneDisplay);
	}
	else if (val==1) //time
	{
		groupBoxTarget->setVisible(true);
		labelTo1->setVisible(false);
		widgetPhaseBounds->setStyle(timeDisplay);
	}
	else if (val==2) //distance
	{
		groupBoxTarget->setVisible(true);
		labelTo1->setVisible(false);
		widgetPhaseBounds->setStyle(floatDisplay);
	}
	else if (val==3 || val==4)
	{
		groupBoxTarget->setVisible(false);
		labelTo1->setVisible(true);
		widgetPhaseBounds->setStyle(intDisplay);
	}
}


void advExBuilder::setAdvExTargetStyle(int pos)
{
	if (pos==0) //free
	{
		labelFrom->setVisible(false);
		labelTo2->setVisible(false);
		widgetPhaseTargetMin->setStyle(noneDisplay);
		widgetPhaseTargetMax->setStyle(noneDisplay);
	}
	else if (pos==1) //sportzone
	{
		labelFrom->setVisible(false);
		labelTo2->setVisible(false);
		widgetPhaseTargetMin->setStyle(intDisplay);
		widgetPhaseTargetMax->setStyle(noneDisplay);
	}
	else if (pos==2  ) //hr absolute
	{
		labelFrom->setVisible(true);
		labelTo2->setVisible(true);
		widgetPhaseTargetMin->setStyle(intDisplay);
		widgetPhaseTargetMax->setStyle(intDisplay);
	}
	else if (pos==3) //hr percent
	{
		labelFrom->setVisible(true);
		labelTo2->setVisible(true);
		widgetPhaseTargetMin->setStyle(intDisplay);
		widgetPhaseTargetMax->setStyle(intDisplay);

	}
	else if (pos==4) //pace
	{
		labelFrom->setVisible(true);
		labelTo2->setVisible(true);
		widgetPhaseTargetMin->setStyle(timeDisplay);
		widgetPhaseTargetMax->setStyle(timeDisplay);
	}
	else if (pos==5) //speed
	{
		labelFrom->setVisible(true);
		labelTo2->setVisible(true);
		widgetPhaseTargetMin->setStyle(floatDisplay);
		widgetPhaseTargetMax->setStyle(floatDisplay);
	}
}


void advExBuilder::getExercises()
{
	//init_session();
	if (internals->IRDAok)
	{
		if (mode==ADVANCEDEX) _getAdvancedExos(*exList);
		else _getTraining(*exList);

		for (int i=tableWidgetAdvancedEx->rowCount()-1;i>=0;--i) tableWidgetAdvancedEx->removeRow(i);
	
		for (unsigned int i=0;i<	exList->size();i++)
		{
			QTableWidgetItem *name = new QTableWidgetItem((char*)exList->exo[i].name);
			//name->setFlags(Qt::ItemIsEnabled);
			int row = tableWidgetAdvancedEx->rowCount();
			tableWidgetAdvancedEx->insertRow(row);
			tableWidgetAdvancedEx->setItem(row, 0, name);
		}
	}
}


void advExBuilder::newExercise()
{
	if (exList->size()<exList->maximumNumberOfExercises)
	{
		polarLINUXio_advancedExo tmp;
		exList->exo.push_back(tmp);
	
		unsigned char name0[]="newExo";
		memcpy(exList->exo[exList->size()-1].name,name0,sizeof(name0));
		QTableWidgetItem *name = new QTableWidgetItem((char*)exList->exo[exList->size()-1].name);
	
		//name->setFlags(Qt::ItemIsEnabled);
		int row = tableWidgetAdvancedEx->rowCount();
		tableWidgetAdvancedEx->insertRow(row);
		tableWidgetAdvancedEx->setItem(row, 0, name);
		exList->exo[exList->size()-1].numPhases=0;
		savendisplayExercise(exList->size()-1);
	}
}


void advExBuilder::deleteExercise()
{
	if (exList->size()>=1)
	{
		exList->exo.erase(exList->exo.begin()+displayedExercise);
		tableWidgetAdvancedEx->removeRow(displayedExercise);
		if (exList->size()!=0) displayedExercise=0;
		else displayedExercise=-1;
		displayExercise(displayedExercise);
	}
}



void advExBuilder::newPhase()
{
	if (displayedExercise!=-1)
	{
	if (exList->exo[displayedExercise].numPhases<12)
	{
		int numP=exList->exo[displayedExercise].numPhases+1;
		exList->exo[displayedExercise].numPhases=numP;
		unsigned char name0[]="newPhase";
		memcpy(exList->exo[displayedExercise].p[numP-1].phasename,name0,sizeof(name0));
		QTableWidgetItem *name = new QTableWidgetItem((char*)exList->exo[displayedExercise].p[numP-1].phasename);
		//name->setFlags(Qt::ItemIsEnabled);
		comboBoxRepeatToPhase->addItem(QString::number(numP)+" - "+QString((char*)name0));
		int row = tableWidgetPhases->rowCount();
		tableWidgetPhases->insertRow(row);
		tableWidgetPhases->setItem(row, 0, name);
		savendisplayPhase (numP-1);
	}
	}
}


void advExBuilder::deletePhase()
{
	polarLINUXio_advancedExo* pp= &exList->exo[displayedExercise];
	if (pp->numPhases>=1)
	{
		pp->numPhases-=1;

		memcpy(&pp->p[displayedPhase],&pp->p[displayedPhase+1],\
		(pp->numPhases-displayedPhase)*sizeof(phase));
		tableWidgetPhases->removeRow(displayedPhase);
		comboBoxRepeatToPhase->removeItem(displayedPhase);
		if (pp->numPhases!=0) displayedPhase=0;
		else displayedPhase=-1;
		displayPhase(displayedPhase);
	}
}



void advExBuilder::setExercises()
{
	//init_session();
	if (displayedExercise!=-1 || exList->size()==0)
	{
		if (displayedPhase!=-1) savendisplayPhase(displayedPhase);
		savendisplayExercise (displayedExercise);
		if (internals->IRDAok) _setAdvancedExos(*exList);
	}
	//close_session();
}



void advExBuilder::savendisplayPhase(int row)
{
	//save last one if displayed
	if (displayedPhase!=-1) savePhase(displayedPhase);
	displayPhase(row);
}

void advExBuilder::displayPhase(int row)
{
	displayedPhase=row;
	int durationtype;
	phase *p=&exList->exo[displayedExercise].p[row];
	if (p->durationtype>=9)
	{
		comboBoxstartMode->setCurrentIndex(1);
		durationtype=p->durationtype-8;
	}
	else
	{
		comboBoxstartMode->setCurrentIndex(0);
		durationtype=p->durationtype;
	}

	comboBoxPhaseBound->setCurrentIndex(durationtype-1);
	if (p->guidetype==0x04) comboBoxPhaseTarget->setCurrentIndex(0); //Free
	else if (p->guidetype==0x18) comboBoxPhaseTarget->setCurrentIndex(1); //sportzone
	else if (p->guidetype==0x14 && p->durationtype!=4 && p->durationtype!=5) comboBoxPhaseTarget->setCurrentIndex(2); //hr abs
	else if (p->guidetype==0x15) comboBoxPhaseTarget->setCurrentIndex(3); //hr %
	else if (p->guidetype==0x34) comboBoxPhaseTarget->setCurrentIndex(4); //pace
	else if (p->guidetype==0x24) comboBoxPhaseTarget->setCurrentIndex(5); //speed
	else comboBoxPhaseTarget->setCurrentIndex(-1);


	comboBoxRepeatNumber->setCurrentIndex(p->repeatNUM-1); //repeat once is row zero of the comboBox
	
	unsigned int idx=p->repeatWhat==0?row:p->repeatWhat-1;
	comboBoxRepeatToPhase->setCurrentIndex(idx);

	widgetPhaseBounds->setValue(p->duration1,p->duration2);
	widgetPhaseTargetMin->setValue(p->FClow[0],p->FClow[1]);
	widgetPhaseTargetMax->setValue(p->FCHigh[0],p->FCHigh[1]);
	
	if (durationtype==2) //time
	{
		widgetPhaseBounds->setValue(hexa_to_same_decimal(p->duration1),hexa_to_same_decimal(p->duration2));
	}
	else if (durationtype==3) //distance
	{
		int val = msb_lsb_to_decimal(p->duration1,p->duration2);
		int up = (int)(val/100);
		int down = val-up*100;
		widgetPhaseBounds->setValue(up,down);
	}
	else if (durationtype==4 || durationtype==5) //hr increase/decrease
	{
		widgetPhaseBounds->setValue(p->duration2,p->duration1);
	}
	
	
	
	//set_display_style2(int pos);
	if (p->guidetype==0x34) //pace
	{
		int valmin = msb_lsb_to_decimal(p->FClow[1],p->FClow[0]);
		int valmax = msb_lsb_to_decimal(p->FCHigh[1],p->FCHigh[0]);

		widgetPhaseTargetMin->setValue(valmin/600,(valmin%600)/10);
		widgetPhaseTargetMax->setValue(valmax/600,(valmax%600)/10);
	}
	else if (p->guidetype==0x24) //speed
	{
		widgetPhaseTargetMin->setValue(p->FClow[1],(1000*p->FClow[0])/255);
		widgetPhaseTargetMax->setValue(p->FCHigh[1],(1000*p->FCHigh[0])/255);
	}
	else
	{
		std::cout<<"not impl"<<std::endl;
	}
	
	internals->adv_graph->setWorkingExercise(&exList->exo[displayedExercise]);
	view->removeGraphs();
	view->addGraph(internals->adv_graph);
	view->plotPage();
}



void advExBuilder::savendisplayExercise (int row)
{
	if (displayedExercise!=-1)
	{
	  if (displayedPhase!=-1)
	  {
		savePhase(displayedPhase);
		displayedPhase=-1;
	  }
	  saveExercise(displayedExercise);
	}
	displayExercise(row);
}

void advExBuilder::displayExercise (int row)
{
	if (exList->size()!=0)
	{
		displayedExercise=row;

		for (int i=tableWidgetPhases->rowCount()-1;i>=0;--i) tableWidgetPhases->removeRow(i);
		comboBoxRepeatToPhase->clear();
		
		for (unsigned int i=0;i<exList->exo[row].numPhases;i++)
		{
			QString phaseName = QString((char*)exList->exo[row].p[i].phasename);
			QTableWidgetItem *name = new QTableWidgetItem(phaseName);
			comboBoxRepeatToPhase->addItem(QString::number(i+1)+" - "+phaseName);
			//name->setFlags(Qt::ItemIsEnabled);

			int row = tableWidgetPhases->rowCount();
			tableWidgetPhases->insertRow(row);
			tableWidgetPhases->setItem(row, 0, name);
		}


		lineEdit_AdvExDesc->setText((char*)exList->exo[row].desc);
		lineEdit_AdvExDesc2->setText((char*)exList->exo[row].desc2);
		
		internals->adv_graph->setWorkingExercise(&exList->exo[displayedExercise]);
		view->removeGraphs();
		view->addGraph(internals->adv_graph);
		view->plotPage();
	}
}


void advExBuilder::saveExercise(int current)
{
	std::string p1,p2,p3;
	
	p1 = tableWidgetAdvancedEx->item(current,0)->text().toStdString();
	//crop size
	p1.resize (10,' ');
	memcpy(exList->exo[current].name,p1.c_str(),10);
	tableWidgetAdvancedEx->item(current,0)->setText(QString(p1.c_str()));

	p2 = lineEdit_AdvExDesc->text().toStdString ();
	p2.resize (20,' ');
	memcpy(exList->exo[current].desc,p2.c_str(),20);
	
	p3 = lineEdit_AdvExDesc2->text().toStdString ();
	p3.resize (10,' ');
	memcpy(exList->exo[current].desc2,p3.c_str(),10);
}



void advExBuilder::savePhase(int current)
{
	phase *p=&exList->exo[displayedExercise].p[current];

	std::string pname = tableWidgetPhases->item(current,0)->text().toStdString();

	//crop size
	pname.resize (10,' ');
	memcpy(p->phasename,pname.c_str(),10);
	tableWidgetPhases->item(current,0)->setText(QString(pname.c_str()));

	
	p->durationtype=(comboBoxPhaseBound->currentIndex()+1)+8*comboBoxstartMode->currentIndex();
	int durationtype=p->durationtype;
	if (durationtype>=9) durationtype-=8;
	
	if (comboBoxPhaseTarget->currentIndex()==0) p->guidetype=0x04; 
	else if (comboBoxPhaseTarget->currentIndex()==1) p->guidetype=0x18;
	else if (comboBoxPhaseTarget->currentIndex()==2) p->guidetype=0x14;
	else if (comboBoxPhaseTarget->currentIndex()==3) p->guidetype=0x15;
	else if (comboBoxPhaseTarget->currentIndex()==4) p->guidetype=0x34;
	else if (comboBoxPhaseTarget->currentIndex()==5) p->guidetype=0x24;

	p->repeatNUM=comboBoxRepeatNumber->currentIndex()+1;//repeat once is row zero of the comboBox
	p->repeatWhat=comboBoxRepeatToPhase->currentIndex()+1;
	if (current==comboBoxRepeatToPhase->currentIndex()) p->repeatWhat=0; //repeat self

	if (durationtype==2)
	{
		p->duration1=decimal_to_same_hexa(widgetPhaseBounds->valueLeft());
		p->duration2=decimal_to_same_hexa(widgetPhaseBounds->valueRight());
	}
	else if (durationtype==3) 
	{
		int value = 100* widgetPhaseBounds->valueLeft()+widgetPhaseBounds->valueRight();
		int_to_msb_lsb(value, &p->duration1, &p->duration2);
	}
	else if (durationtype==4 || durationtype==5)
	{
		p->duration1=(widgetPhaseBounds->valueRight());
		p->duration2=(widgetPhaseBounds->valueLeft());
	}
	else
	{
		p->duration1=widgetPhaseBounds->valueLeft();
		p->duration2=widgetPhaseBounds->valueRight();
	}


	if (p->guidetype==0x34) //pace
	{
		int value = widgetPhaseTargetMin->valueLeft()*600+widgetPhaseTargetMin->valueRight()*10;
		int_to_msb_lsb(value, &p->FClow[1], &p->FClow[0]);

		int value2 = widgetPhaseTargetMax->valueLeft()*600+widgetPhaseTargetMax->valueRight()*10;
		int_to_msb_lsb(value2, &p->FCHigh[1], &p->FCHigh[0]);
	}
	else if (p->guidetype==0x24) //speed
	{
	p->FClow[0]=1.0*widgetPhaseTargetMin->valueRight()*0.255;
	p->FCHigh[0]=1.0*widgetPhaseTargetMax->valueRight()*0.255;
	}
	else
	{
		p->FClow[0]=widgetPhaseTargetMin->valueLeft();
		p->FClow[1]=widgetPhaseTargetMin->valueRight();
		p->FCHigh[0]=widgetPhaseTargetMax->valueLeft();
		p->FCHigh[1]=widgetPhaseTargetMax->valueRight();
	}
}

